/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Xml.XPath;
using DaveSexton.DocProject.Sandcastle.BuildComponents.TypeConverters.BuiltIn;
using System.Xml;

namespace DaveSexton.DocProject.Sandcastle.BuildComponents.Editors.BuiltIn
{
	internal sealed partial class SyntaxComponentEditorDialog : DaveSexton.DocProject.Sandcastle.BuildComponents.Editors.CancelableBaseEditorDialog
	{
		#region Public Properties
		#endregion

		#region Private / Protected
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ResolveReferenceLinksComponent2EditorDialog" /> class.
		/// </summary>
		public SyntaxComponentEditorDialog()
		{
			InitializeComponent();
		}
		#endregion

		#region Methods
		protected override void UpdateForBuildComponent(SandcastleBuildComponent component)
		{
			XPathNavigator navigator = component.CreateNavigator();

			SuspendLayout();

			try
			{
				XPathNavigator syntax = navigator.Clone();

				if (syntax.MoveToChild("syntax", ""))
				{
					inputTextBox.Text = syntax.GetAttribute("input", "");
					outputTextBox.Text = syntax.GetAttribute("output", "");
				}
				else
				{
					inputTextBox.Text = null;
					outputTextBox.Text = null;
				}

				generatorsBindingSource.DataSource = CreateGeneratorsDataTable(navigator);
			}
			finally
			{
				ResumeLayout();
			}
		}

		private static DataTable CreateGeneratorsDataTable(IXPathNavigable component)
		{
			DataTable table = new DataTable();
			table.Locale = System.Globalization.CultureInfo.CurrentCulture;

			DataColumn column = table.Columns.Add("type", typeof(string));
			column.AllowDBNull = false;
			column.DefaultValue = string.Empty;

			column = table.Columns.Add("assembly", typeof(string));
			column.AllowDBNull = false;
			column.DefaultValue = string.Empty;

			FillGeneratorsDataTable(component, table);

			return table;
		}

		private static void FillGeneratorsDataTable(IXPathNavigable component, DataTable table)
		{
			XPathNavigator navigator = component.CreateNavigator();

			if (navigator.MoveToChild("generators", ""))
			{
				foreach (XPathNavigator generator in navigator.SelectChildren("generator", ""))
				{
					DataRow row = table.NewRow();
					row["type"] = generator.GetAttribute("type", "");
					row["assembly"] = generator.GetAttribute("assembly", "");
					table.Rows.Add(row);
				}
			}
		}

		private void SaveChanges(DataTable table)
		{
			XPathNavigator navigator = BuildComponent.CreateNavigator();

			StringBuilder output = new StringBuilder(Math.Max(navigator.InnerXml.Length, 256));

			XmlWriterSettings settings = new XmlWriterSettings();
			settings.ConformanceLevel = ConformanceLevel.Fragment;
			settings.Indent = true;

			using (XmlWriter writer = XmlWriter.Create(output, settings))
			{
				SaveSyntax(writer);
				SaveGeneratorsDataTable(writer, table);
			}

			navigator.InnerXml = output.ToString();
		}

		private void SaveSyntax(XmlWriter writer)
		{
			writer.WriteStartElement("syntax");
			writer.WriteAttributeString(null, "input", null, inputTextBox.Text);
			writer.WriteAttributeString(null, "output", null, outputTextBox.Text);
			writer.WriteEndElement();
		}

		private static void SaveGeneratorsDataTable(XmlWriter writer, DataTable table)
		{
			writer.WriteStartElement("generators");

			foreach (DataRow row in table.Rows)
			{
				writer.WriteStartElement("generator");
				writer.WriteAttributeString(null, "type", null, (string) row["type"]);
				writer.WriteAttributeString(null, "assembly", null, (string) row["assembly"]);
				writer.WriteEndElement();
			}

			writer.WriteEndElement();
		}

		protected override bool SaveChanges()
		{
			if (!ValidateChildren())
				return false;

			DataTable table = generatorsBindingSource.DataSource as DataTable;

			if (table != null)
				SaveChanges(table);

			return true;
		}
		#endregion

		#region Event Handlers
		private void generatorsDataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
		{
			e.Cancel = true;
		}
		#endregion
	}
}